package com.haima.sage.bigdata.api.frame.process.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.haima.sage.bigdata.api.common.DbUtils;
import com.haima.sage.bigdata.api.entity.api.Api;
import com.haima.sage.bigdata.api.frame.process.ApiProcess;
import com.haima.sage.bigdata.api.entity.api.data.ApiData;
import com.haima.sage.bigdata.api.entity.api.data.cases.Case;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class DbApiProcess extends BaseApiProcess<Connection, ResultSet> {
    private static final Logger LOG = LogManager.getLogger(DbApiProcess.class);

    private DbApiProcess(Api api, ApiData data, Case item) throws Exception {
        super(api, data, item);
    }

    @Override
    protected Connection getClient() throws Exception {
        String key = "default";
        if (item.getConfig().getStorage() != null) {
            key = item.getConfig().getStorage();
        }
        return DbUtils.getConnection(key);
    }

    @Override
    protected ResultSet getResult(String sql, Connection conn) throws SQLException {
        return DbUtils.getResult(sql, conn);
    }

    public static ApiProcess build(Api api, ApiData data, Case item) throws Exception {
        return new DbApiProcess(api, data, item);
    }


    @Override
    public Map<String, Object> getRowResult(String sql, ResultSet rs) throws SQLException {
        return DbUtils.getRowResult(sql ,rs);
    }

    public Map<String, Object> getRecord(ResultSet rs, ResultSetMetaData metaData, int columnCount) throws SQLException {
        Map<String, Object> map = new HashMap<>();
        for (int i = 1; i <= columnCount; i++) {
            String key = metaData.getColumnLabel(i);
            int type = metaData.getColumnType(i);
            Object obj = DbUtils.getDbValue(rs, i, type);
            map.put(key, obj);
        }
        return doFilter(map);
    }

    @Override
    public Object getPagerResult(String sql, ResultSet rs) throws SQLException {
        return getListResult(sql, rs);
    }

    @Override
    public Object getColumnResult(String sql, ResultSet rs) throws SQLException {
        if (rs.next()) {
            ResultSetMetaData metaData = rs.getMetaData();
            int type = metaData.getColumnType(1);
            return DbUtils.getDbValue(rs, 1, type);
        }
        return null;
    }

    @Override
    public List<Map<String, Object>> getListResult(String sql, ResultSet rs) throws SQLException {
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();

        List<Map<String, Object>> list = new ArrayList<>();
        while (rs.next()) {
            Map<String, Object> map = getRecord(rs, metaData, columnCount);
            list.add(map);
            if (list.size() >= data.getMaxBatchSize()) {
                break;
            }
        }
        return list;
    }

}
